package atomic

import (
	"fmt"
	"sync"
	"sync/atomic"
)

// 原子操作api
func AtomicCase() {
	var count int32 = 5
	atomic.StoreInt32(&count, 10)                     // 重新赋值
	fmt.Println("获取count：", atomic.LoadInt32(&count)) // 10  获取变量的值
	// 原有基础上+10
	fmt.Println("原有基础上+10后的值：", atomic.AddInt32(&count, 10)) // 20
	//交换变量的值 30 ，返回原有的值 20
	fmt.Println("原有基础上+10后的值：", atomic.SwapInt32(&count, 30)) //  20
	fmt.Println("获取count：", atomic.LoadInt32(&count))         // 获取变量的值： 30
	// 比较并替换原来的值，返回是否替换成功
	fmt.Println("比较并替换原来的值，返回是否替换成功：", atomic.CompareAndSwapInt32(&count, 30, 10))
	fmt.Println("获取count：", atomic.LoadInt32(&count)) // 获取变量的值： 10
}

// 加锁确保数据安全
func AtomicCase1() {
	var count int64
	wg := sync.WaitGroup{}
	lock := sync.Mutex{}
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			lock.Lock()
			count += 1
			lock.Unlock()
		}()
	}
	wg.Wait()
	fmt.Println(count) // 如果不加锁，最后返回就不能确定是100
}

// 不加锁使用原子操作确保数据安全
func AtomicCase2() {
	var count int64
	wg := sync.WaitGroup{}
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			atomic.AddInt64(&count, int64(1)) // 循环每次+1
		}()
	}
	wg.Wait()
	fmt.Println(count) // 如果不加锁，最后返回就不能确定是100
}
